// 手写Promise构造函数

function Promise(executor) {
  this.promiseStatus = "pedding";
  this.promiseReslut = null;
  //  保存异步时，then要执行的函数，then方法，可以连续调用
  this.callBacks = [];

  const reslove = (data) => {
    // 保证reslove，reject只能执行一次
    if (this.promiseStatus != "pedding") return;
    this.promiseStatus = "fulfilled";
    this.promiseReslut = data;

    setTimeout(() => {
      this.callBacks.forEach((item) => {
        item.onResloved();
      });
    });
  };

  const rejecet = (data) => {
    // 保证reslove，reject只能执行一次
    if (this.promiseStatus != "pedding") return;
    this.promiseStatus = "rejected";
    this.promiseReslut = data;
    setTimeout(() => {
      this.callBacks.forEach((item) => {
        item.onResloved(data);
      });
    });
  };

  //   解决执行器里thorw抛出异常
  try {
    // 执行器
    executor(reslove, rejecet);
  } catch (error) {
    rejecet(error);
  }
}

// then方法

Promise.prototype.then = function (onResloved, onRejeceted) {
  // 处理promise穿透问题，then的连续调用，或者不传参数
  if (typeof onResloved !== "function") {
    onResloved = (val) => val;
  }
  if (typeof onRejeceted != "function") {
    onRejeceted = (err) => {
      throw err;
    };
  }

  // return promise 是因为要处理，then的返回值，它也是一个promise
  return new Promise((reslove, reject) => {
    // 封装方法(处理then的返回值，返回的是promise对象，同时要修改其结果和状态)
    const callBack = (typeFn) => {
      try {
        let reslut = typeFn(this.promiseReslut);

        if (reslut instanceof Promise) {
          // 如果返回的是 一个promise实例
          reslut.then(
            (res) => {
              reslove(res);
            },
            (err) => {
              reject(err);
            }
          );
        } else {
          // 返回的不是prommise实例
          reslove(reslut);
        }
      } catch (error) {
        reject(error);
      }
    };

    // 处理同步的成功
    if (this.promiseStatus == "fulfilled") {
      setTimeout(() => {
        callBack(onResloved);
      });
    }

    // 处理同步的失败
    if (this.promiseStatus == "rejected") {
      setTimeout(() => {
        callBack(onResloved);
      });
    }

    // 处理异步
    if (this.promiseStatus == "pedding") {
      this.callBacks.push({
        onResloved: () => {
          callBack(onResloved);
        },
        onRejeceted: () => {
          callBack(onRejeceted);
        },
      });
    }
  });
};

// catch方法

Promise.prototype.catch = function (onRejeceted) {
  return this.then(undefined, onRejeceted);
};

// reslove方法
Promise.resolve = function (val) {
  return new Promise((reslove, reject) => {
    if (val instanceof Promise) {
      val.then(
        (res) => {
          reslove(res);
        },
        (err) => {
          reject(err);
        }
      );
    } else {
      reslove(val);
    }
  });
};

// reject方法 返回的都是失败的promise对象

Promise.rejecet = function (val) {
  return new Promise((reslove, reject) => {
    if (val instanceof Promise) {
      val.then(
        (res) => {
          reject(res);
        },
        (err) => {
          reject(err);
        }
      );
    } else {
      reject(val);
    }
  });
};

// all 全部成功，返回状态为成功，结果为全部成功的返回值数组，只要有一个失败，状态就失败，结果为失败的那个返回值

Promise.all = function (arr) {
  let num = 0;
  let reslutArr = [];
  return new Promise((reslove, reject) => {
    for (let i = 0; i < arr.length; i++) {
      arr[i].then(
        (res) => {
          num++;
          //  表示全部的promise执行成功
          if (num == arr.length) {
            console.log(12);

            reslutArr[0] = res;
            //    返回对应的结果，该变状态
            reslove(arr);
          }
        },
        (err) => {
          reject(err);
        }
      );
    }
  });
};

// race 谁先执行，就返回谁，状态也是

Promise.race = function (arr) {
  return new Promise((reslove, rejecet) => {
    for (let i = 0; i < arr.length; i++) {
      arr[i].then(
        (res) => {
          reslove(res);
        },
        (err) => {
          rejecet(err);
        }
      );
    }
  });
};
